Firebird - rychlost insertu
Otázka od: Tomas Bradle
28. 8. 2004 13:42
Zdravim vsechny,
mam aplikaci, ktera zapisuje do protokolu hlaseni o sve cinnosti - do tabuly
ERRLOG se sloupecky ID(integer), TS(timestamp), MSG(varchar). Behem
zkusebniho provozu (cca 3 tydny) se tam nahromadilo cca 65 tis. zaznamu. Na
before insert triggeru mam mechanizmus zjistovani, jestli zaznam se stejnym
ID jiz existuje
DECLARE VARIABLE CNT INTEGER;
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID=gen_id(ID_ERRLOG, 1)*100+STATION_ID();
SELECT COUNT(*) FROM ERRLOG WHERE ID=NEW.ID INTO :CNT;
IF (:CNT > 0) THEN
NEW.ID=-1;
END
a v after insert triggeru mam
DELETE FROM ERRLOG WHERE ID=-1;
tato kombinace prakticky zpusobi, ze pokus o vlozeni jiz existujiciho
zaznamu bude ignorovan. To je jev, ktery se vzhledem k povaze aplikace muze
vyskytnout cca jedenkratza 500-1000 zaznamu a nelze (!!!) jej vyloucit (je
to pripad, kdy (NEW.ID IS NOT NULL)).
Pri odmerovani doby vykonavani jednotlivych insertu (kazdy insert je
samozrejme v samostatne transakci) mi vysla doba cca 800 ms. Po vymazani cca
30 tis zaznamu z cela tabulky (tech nejstarsich) se zkratila doba cca na 200
ms.
Mam dotazy:
1. jaky je duvod tohoto zkraceni ? - chtel bych lepe pochopit cinnost FB
2. je mi jasne, ze uvedeny SELECT count(*) muze byt zasove narocny (?),
existuje neco rychlejsiho ? (o moznosti nechat to spadnout na exception
uvazuji)
3. chci samozrejme udelat nejake automaticke odmazavani, jeste jsem se
nerozhodl jak - jaka by byla nejlepsi metoda ?
diky
Tomas Bradle
t.bradle@worldonline.cz
Odpovedá: Jakub Dusek
28. 8. 2004 14:06
Pole ID tabulky ERRLOG je primarni klic? Pokud ne, je na nej vytvoren
index?
Jakub Dusek
----------------------------------------------------------------------
web: http://www.corexpert.com, mobile: +420 604 615 795, ICQ: 86063232
odesilani smsek, vizitek, log a melodii, snadna integrace do Vaseho IS
=> Sms GateKeeper, Sms GateKeeper Service
======================================================================
Saturday, August 28, 2004, 2:42:04 PM, you wrote:
TB> SELECT COUNT(*) FROM ERRLOG WHERE ID=NEW.ID INTO :CNT;
Odpovedá: Tomas Bradle
28. 8. 2004 14:38
No jo, ja tam ten index opravdu nemam, myslel jsem, ze jo a nenapadlo me se
podivat, takze jako u 90% zavad, zase nejaka "blbost"...
Ted uz je to cca 20 ms.
diky
Tomas Bradle
t.bradle@worldonline.cz
----- Original Message -----
From: "Jakub Dusek" <delphi@corexpert.com>
To: <delphi-l@clexpert.cz>
Sent: Saturday, August 28, 2004 3:06 PM
Subject: Re: Firebird - rychlost insertu
> Pole ID tabulky ERRLOG je primarni klic? Pokud ne, je na nej vytvoren
> index?
>
> Jakub Dusek
>
Odpovedá: Tomas Michalik
28. 8. 2004 17:32
Tomas Bradle wrote:
> Zdravim vsechny,
>
> mam aplikaci, ktera zapisuje do protokolu hlaseni o sve cinnosti - do tabuly
> ERRLOG se sloupecky ID(integer), TS(timestamp), MSG(varchar). Behem
> zkusebniho provozu (cca 3 tydny) se tam nahromadilo cca 65 tis. zaznamu. Na
> before insert triggeru mam mechanizmus zjistovani, jestli zaznam se stejnym
> ID jiz existuje
>
> DECLARE VARIABLE CNT INTEGER;
> BEGIN
> IF (NEW.ID IS NULL) THEN
> NEW.ID=gen_id(ID_ERRLOG, 1)*100+STATION_ID();
> SELECT COUNT(*) FROM ERRLOG WHERE ID=NEW.ID INTO :CNT;
> IF (:CNT > 0) THEN
> NEW.ID=-1;
> END
Tam, kde nemusis, se nezdrzuj volanim "select count(*)", ale pouzij
konstrukci "if exists"
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID=gen_id(ID_ERRLOG, 1)*100+STATION_ID();
if (exists (select *
from ERRLOG
where WHERE ID=NEW.ID)) then
NEW.ID=-1;
END
========================
Tomas Michalik
vyvoj IS
ProCA, spol. s r.o.
V Luzich 818
Praha 4 - Libus
140 00, Czech Republic
tel: +420 234646446
fax: +420 234646120
michalik@proca.cz
http://www.proca.cz
Odpovedá: Slavomir Skopalik
29. 8. 2004 12:57
Me se ta kontrukce vubec nelibi.
Proc slozite testuji, vkladam a pak zase mezu, kdyz to jde velmi
jednoduse.
1. Bud mohu nechat vkladani spadnout na vyjimku a tu osetrit na urovni
aplikace
2. Nebo mohu si napsat uloznou proceduru asi takto
begin
BEGIN
INSERT INTO DeviceData(idDevMeasurandLimit,tValue)VALUES(0,'---');
WHEN ANY DO i=1;
END
end^
Nad ID je samopzrejme primarni klic, ktery provede testy na duplicitu.
Slavek
>
> DECLARE VARIABLE CNT INTEGER;
> BEGIN
> IF (NEW.ID IS NULL) THEN
> NEW.ID=gen_id(ID_ERRLOG, 1)*100+STATION_ID();
> SELECT COUNT(*) FROM ERRLOG WHERE ID=NEW.ID INTO :CNT;
> IF (:CNT > 0) THEN
> NEW.ID=-1;
> END
>
> a v after insert triggeru mam
>
> DELETE FROM ERRLOG WHERE ID=-1;
>
> tato kombinace prakticky zpusobi, ze pokus o vlozeni jiz
> existujiciho zaznamu bude ignorovan. To je jev, ktery se
> vzhledem k povaze aplikace muze vyskytnout cca jedenkratza
> 500-1000 zaznamu a nelze (!!!) jej vyloucit (je to pripad,
> kdy (NEW.ID IS NOT NULL)).
>
> Pri odmerovani doby vykonavani jednotlivych insertu (kazdy
> insert je samozrejme v samostatne transakci) mi vysla doba
> cca 800 ms. Po vymazani cca 30 tis zaznamu z cela tabulky
> (tech nejstarsich) se zkratila doba cca na 200 ms.
Odpovedá: Tomas Bradle
30. 8. 2004 11:04
No, nedovedu si predstavit 20 procedur pro 20 tabulek, ale na urovni
aplikace by to snad slo, ted jde jenom o to, jak odlisit chybu primarniho
klice od jinych chyb (nerad bych zahodil platny zaznam, ktery ma byt vlozen,
ale vznikla jina exception)
diky
Tomas
----- Original Message -----
From: "Slavomir Skopalik" <skopalik@elektlabs.cz>
To: <delphi-l@clexpert.cz>
Sent: Sunday, August 29, 2004 1:57 PM
Subject: Re: Firebird - rychlost insertu
> Me se ta kontrukce vubec nelibi.
> Proc slozite testuji, vkladam a pak zase mezu, kdyz to jde velmi
> jednoduse.
>
> 1. Bud mohu nechat vkladani spadnout na vyjimku a tu osetrit na urovni
> aplikace
> 2. Nebo mohu si napsat uloznou proceduru asi takto
>
> begin
> BEGIN
> INSERT INTO DeviceData(idDevMeasurandLimit,tValue)VALUES(0,'---');
> WHEN ANY DO i=1;
> END
> end^
>
>
Odpovedá: Slavomir Skopalik
30. 8. 2004 12:01
Muzes se nadefinovat vlastni exception a pak parsovat exception message.
Treba takto:
except
on E:Exception do begin
if pos('Duplicite serial number',E.Message)<>0then
Sender.EventResult:=_erIdentNumber else Sender.EventResult:=_erDB;
s:=E.Message;
Tim si zarucis osetreni pouze tvoji exception.
Pozor, ve FB je chyba a misto nazvu exception se zobrazuje jeji poradove
cislo, takze musis testovat text.
Slavek
> No, nedovedu si predstavit 20 procedur pro 20 tabulek, ale na
> urovni aplikace by to snad slo, ted jde jenom o to, jak
> odlisit chybu primarniho klice od jinych chyb (nerad bych
> zahodil platny zaznam, ktery ma byt vlozen, ale vznikla jina
> exception)
>
> diky
> Tomas